【xtrabackup - 全量备份恢复】

# 下载xtrabackup工具
https://www.percona.com/downloads
拉到xtrabackup下载界面，根据数据库版本选择对应的版本，MySQL（GreatSQL）5.7以下版本选择2.4
MySQL（GreatSQL）8以上版本选择对应的8版本即可(8版本最好跟数据库版本保持一致)

1. 停止MySQL容器
docker stop mysql8

2. 删除MySQL的data目录下所有文件
cd /data/compose/mysql
rm -rf data/*

3. 解压全量备份文件
tar -xf full_20250702_091002.tar.xz

4. 另外准备mysql.cnf文件，需要提前cp一份
配置中要指定以下三个文件的路径【宿主机路径】
datadir=/data/compose/mysql/data
log-bin=/data/compose/mysql/data/binlog
log-bin-index=/data/compose/mysql/data/binlog.index

5. 使用xtrabaup解压qp压缩文件
cd /root/publish/backups/mysqlbk/backups/full_20250702_091002
xtrabackup --decompress --parallel=4 --target-dir=./

6. 预处理 - 生成一致性备份 【指定执行备份时的mysql.cnf】
/usr/local/xtrabackup/bin/xtrabackup \
  --defaults-file=/root/publish/backups/mysqlbk/backups/mysql.cnf \
  --prepare \
  --target-dir=./

7. 执行数据恢复【target-dir指定备份文件目录，./表示已进入该目录下执行】
/usr/local/xtrabackup/bin/xtrabackup \
  --defaults-file=/root/publish/backups/mysqlbk/backups/mysql.cnf \
  --copy-back \
  --parallel=10 \
  --target-dir=./

8. 权限处理
chown -R mysql:mysql /data/compose/mysql      **** 待验证

9. 启动MySQL
docker start mysql8

——————————————————————————————————————————
# 准备备份文件(该备份来自xtrabackup打包)
解压所有zst文件

# 停止数据库
systemctl stop greatsql

# 删除数据库data目录下的文件
cd /data/greatsql
rm -rf data/*

# 执行xtrabackup恢复数据
/usr/local/percona-xtrabackup-8.0.32-26-Linux-x86_64.glibc2.17/bin/xtrabackup --defaults-file=/etc/my.cnf --copy-back --parallel=10 --target-dir=./
                            xtrabackup程序路径                                       my.cnf文件路径            拷贝                  指定备份文件所在目录

# 给恢复后的data目录下文件赋权
chown -R mysql:mysql data/ 

# 如果启动报错[Different lower_case_table_names settings for server (‘1‘) and data dictionary (‘0‘).]
在my.cnf配置中添加以下内容
[mysqld]
lower_case_table_names = 1

# 启动MySQL
systemctl restart greatsql

# 密码问题
重新恢复数据的mysql密码是按该备份原始的账号密码进行登录

# 连接报错[Connection is being used.]
断开客户端连接，重新打开navicat进行连接即可

======================================================================

【ibd单表恢复推荐方法】- 该方法多个表同时恢复会报错

1. 清空原表数据，只留下表结构

2. 丢弃单表空间 
use sy_dms;
ALTER TABLE dms_data_certificate DISCARD TABLESPACE;

3. 上传原来的ibd文件

4. 修改文件权限
chown mysql:mysql dms_data_certificate.ibd
chmod 640 dms_data_certificate.ibd

5. 重启greatsql（可选）
systemctl restart greatsql.service

4. 重新读取新表空间文件
use sy_dms;
ALTER TABLE dms_data_certificate IMPORT TABLESPACE;


5. 检查表的完整性
use sy_dms; 
CHECK TABLE dms_data_certificate;

========================================================

在 MySQL 中，.ibd 文件是 InnoDB 表的表空间文件，存储了表的实际数据和索引。当你需要恢复一个 MySQL 数据库中的多个表时，你可以按照以下步骤操作：

步骤 1：停止 MySQL 服务
首先，确保 MySQL 服务已经停止，防止数据库正在运行时出现数据损坏。

bash
复制
编辑
sudo systemctl stop mysql
步骤 2：备份当前数据库文件
为了安全起见，备份数据库的当前状态。特别是 ibd 文件、frm 文件、ib_logfile 等关键文件。

bash
复制
编辑
cp /var/lib/mysql/your_database/* /path/to/backup/
步骤 3：恢复 .ibd 文件
将丢失或需要恢复的 .ibd 文件复制到 MySQL 数据库的表空间目录下，通常是 /var/lib/mysql/your_database/。

bash
复制
编辑
cp /path/to/backup/your_table.ibd /var/lib/mysql/your_database/
步骤 4：确保 .frm 文件存在
每个表在 MySQL 中都有一个对应的 .frm 文件，它包含表的结构定义。如果 .frm 文件丢失，恢复表会变得复杂。确认 .frm 文件是否存在并复制到相应目录。

如果你没有 .frm 文件，可以尝试通过表的定义（如 DDL 语句）重新创建。

步骤 5：启用 innodb_file_per_table
确保 MySQL 配置文件（my.cnf 或 my.ini）中的 innodb_file_per_table 选项已经启用，这样每个表的数据和索引都会存储在独立的 .ibd 文件中。

ini
复制
编辑
[mysqld]
innodb_file_per_table = 1
如果你对配置文件进行了修改，重启 MySQL。

步骤 6：使用 innodb_force_recovery 恢复数据（可选）
如果恢复过程中遇到表空间问题，可以使用 innodb_force_recovery 参数。将该参数设置为 1-6 之间的值来强制 InnoDB 引擎跳过某些恢复过程。

在 my.cnf 中设置：

ini
复制
编辑
[mysqld]
innodb_force_recovery = 1
然后重新启动 MySQL。

步骤 7：使用 ALTER TABLE 重建表
一旦 .ibd 文件恢复，你可以使用 ALTER TABLE 语句来重新关联 .ibd 文件与表：

sql
复制
编辑
ALTER TABLE your_table DISCARD TABLESPACE;
ALTER TABLE your_table IMPORT TABLESPACE;
这将重新加载 .ibd 文件，MySQL 会尝试恢复表的结构和数据。

步骤 8：检查表的完整性
恢复过程完成后，检查表的完整性并确保数据无误。

sql
复制
编辑
CHECK TABLE your_table;
注意事项：
恢复过程可能会受到表的损坏情况影响，特别是在缺少 .frm 或 .ibd 文件时。
如果 ibd 文件丢失，且无法恢复，可以尝试通过数据备份或其他方式恢复表。
恢复操作最好先在测试环境中进行，以确保数据的完整性。
如果恢复过程出现问题，可以参考 MySQL 的错误日志，以便定位和解决问题。

========================================================

如果你有很多张表需要批量丢弃表空间（DISCARD TABLESPACE），可以通过编写脚本来自动化这个过程。以下是几种常见的实现方式，主要有两种方法：

方法 1：使用 MySQL 脚本（SQL 方式）
你可以编写一个 SQL 脚本，动态生成 ALTER TABLE ... DISCARD TABLESPACE 语句，并在 MySQL 中执行这些语句。假设你已经知道要丢弃表空间的数据库名称，以下是一个 SQL 查询，可以列出数据库中的所有表，并为每张表生成 DISCARD TABLESPACE 语句。

步骤：
连接到 MySQL 数据库。
执行以下 SQL 脚本，生成 DISCARD TABLESPACE 语句。
sql
复制
编辑
SELECT CONCAT('ALTER TABLE ', table_schema, '.', table_name, ' DISCARD TABLESPACE;')
FROM information_schema.tables
WHERE table_schema = 'your_database_name' 
AND table_type = 'BASE TABLE';
这个查询会输出类似以下的结果：

sql
复制
编辑
ALTER TABLE your_database_name.table1 DISCARD TABLESPACE;
ALTER TABLE your_database_name.table2 DISCARD TABLESPACE;
ALTER TABLE your_database_name.table3 DISCARD TABLESPACE;
将输出的 SQL 语句复制到一个 SQL 文件中，然后执行。
你可以通过 mysql 命令行工具批量执行生成的 SQL 文件：

bash
复制
编辑
mysql -u your_user -p your_database < discard_tablespace.sql


方法 2：使用 Bash 脚本（Linux 系统）
如果你想通过 Bash 脚本自动执行这些操作，你可以通过脚本循环遍历数据库中的表，并使用 MySQL 命令执行 DISCARD TABLESPACE。

步骤：
使用以下 Bash 脚本来获取所有表，并批量执行 DISCARD TABLESPACE。
bash
复制
编辑
#!/bin/bash

# 数据库配置
DB_NAME="your_database_name"
USER="your_mysql_user"
PASSWORD="your_mysql_password"

# 获取表名并丢弃表空间
TABLES=$(mysql -u $USER -p$PASSWORD -D $DB_NAME -Bse "SHOW TABLES")

for TABLE in $TABLES
do
  echo "Running: ALTER TABLE $DB_NAME.$TABLE DISCARD TABLESPACE;"
  mysql -u $USER -p$PASSWORD -D $DB_NAME -e "ALTER TABLE $DB_NAME.$TABLE DISCARD TABLESPACE;"
done
将脚本保存为 discard_tablespace.sh，然后给予执行权限并运行：
bash
复制
编辑
chmod +x discard_tablespace.sh
./discard_tablespace.sh




方法 3：使用 Python 脚本（跨平台）
你也可以使用 Python 编写一个简单的脚本，通过 MySQL Connector 库来执行批量丢弃表空间的操作。

步骤：
首先，确保安装了 MySQL Connector：
bash
复制
编辑
pip install mysql-connector-python
然后使用以下 Python 脚本：
python
复制
编辑
import mysql.connector

# MySQL 配置
db_config = {
    'host': 'localhost',
    'user': 'your_mysql_user',
    'password': 'your_mysql_password',
    'database': 'your_database_name'
}

# 连接到 MySQL
conn = mysql.connector.connect(**db_config)
cursor = conn.cursor()

# 获取所有表
cursor.execute("SHOW TABLES")
tables = cursor.fetchall()

# 执行 DISCARD TABLESPACE
for (table,) in tables:
    print(f"Running: ALTER TABLE {table} DISCARD TABLESPACE;")
    cursor.execute(f"ALTER TABLE {table} DISCARD TABLESPACE;")
    
# 提交并关闭连接
conn.commit()
cursor.close()
conn.close()

print("All tables processed.")
保存脚本为 discard_tablespace.py，然后运行：
bash
复制
编辑
python discard_tablespace.py
小结
SQL 方法：直接在 MySQL 中通过 information_schema 获取表名并生成 SQL 语句。
Bash 脚本方法：适用于 Linux 系统，自动化地对每张表执行 DISCARD TABLESPACE。
Python 脚本方法：适用于跨平台，灵活性更高，适用于较复杂的自动化任务。
根据你的需求，你可以选择适合的批量丢弃表空间的方式。